/**
 ******************************************************************************
 * @file    py32f030_hal_msp.c
 * @author  MCU SYSTEM Team
 * @Version V1.0.0
 * @Date    2020-10-19
 * @brief   This file provides code for the MSP Initialization
 *          and de-Initialization codes.
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "BSP.h"

static DMA_HandleTypeDef HdmaCh1;
static DMA_HandleTypeDef HdmaCh2;

/**
 * Initializes the Global MSP.
 */
void HAL_MspInit(void)
{
	/* USER CODE BEGIN MspInit 0 */
	__HAL_RCC_SYSCFG_CLK_ENABLE();
	/* USER CODE END MspInit 0 */
}

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	// SPI1 ³õÊ¼»¯
	if (hspi->Instance == SPI1)
	{
		/*##-1- Enable peripherals and GPIO Clocks #################################*/
		/* Enable GPIO TX/RX clock */
		__HAL_RCC_GPIOB_CLK_ENABLE();
		__HAL_RCC_GPIOA_CLK_ENABLE();
		/* Enable SPI clock */
		__HAL_RCC_SPI1_CLK_ENABLE();
		__HAL_RCC_DMA_CLK_ENABLE();
		/*
			PB3-SCK	(AF0)
			PB4-MISO(AF0)
			PB5-MOSI(AF0)
			PA15-NSS(AF0)
		*/
		// SPI CS
		GPIO_InitStruct.Pin = GPIO_PIN_15;
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

		if (hspi->Init.CLKPolarity == SPI_POLARITY_LOW)
		{
			GPIO_InitStruct.Pull = GPIO_PULLDOWN; //  GPIO_PULLUP
		}
		else
		{
			GPIO_InitStruct.Pull = GPIO_PULLUP; //  GPIO_PULLUP
		}

		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
		/* SPI SCK GPIO pin configuration  */
		GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		// GPIO_InitStruct.Pull      = GPIO_PULLUP;//GPIO_PULLDOWN;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

		////INT
		HAL_NVIC_SetPriority(SPI1_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(SPI1_IRQn);
		// damÅäÖÃ

		// damÅäÖÃ

		/*##-3- Configure the DMA ##################################################*/
		/* Configure the DMA handler for Transmission process */
		HdmaCh1.Instance = DMA1_Channel1;
		HdmaCh1.Init.Direction = DMA_MEMORY_TO_PERIPH;
		HdmaCh1.Init.PeriphInc = DMA_PINC_DISABLE;
		HdmaCh1.Init.MemInc = DMA_MINC_ENABLE;
		if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
		{
			HdmaCh1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
			HdmaCh1.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		}
		else
		{
			HdmaCh1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
			HdmaCh1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
		}
		HdmaCh1.Init.Mode = DMA_NORMAL;
		HdmaCh1.Init.Priority = DMA_PRIORITY_VERY_HIGH;

		HAL_DMA_Init(&HdmaCh1);

		/* Associate the initialized DMA handle to the the SPI handle */
		__HAL_LINKDMA(hspi, hdmatx, HdmaCh1);

		/* Configure the DMA handler for Transmission process */
		HdmaCh2.Instance = DMA1_Channel2;

		HdmaCh2.Init.Direction = DMA_PERIPH_TO_MEMORY;
		HdmaCh2.Init.PeriphInc = DMA_PINC_DISABLE;
		HdmaCh2.Init.MemInc = DMA_MINC_ENABLE;
		if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
		{
			HdmaCh2.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
			HdmaCh2.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
		}
		else
		{
			HdmaCh2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
			HdmaCh2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
		}
		HdmaCh2.Init.Mode = DMA_NORMAL;
		HdmaCh2.Init.Priority = DMA_PRIORITY_HIGH;

		HAL_DMA_Init(&HdmaCh2);

		DMA1_Channel1->CCR &= ~(3 << 12);
		DMA1_Channel1->CCR |= (0 << 12);
		DMA1_Channel2->CCR &= ~(3 << 12);
		DMA1_Channel2->CCR |= (3 << 12);
		//    /* Associate the initialized DMA handle to the the SPI handle */
		__HAL_LINKDMA(hspi, hdmarx, HdmaCh2);

		HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 1);
		HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

		HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 1, 1);
		HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
	}
	//	else if(hspi->Instance == SPI2)
	//	{
	//		 /*##-1- Enable peripherals and GPIO Clocks #################################*/
	//		/* Enable GPIO TX/RX clock */
	//		__HAL_RCC_GPIOA_CLK_ENABLE();
	//		__HAL_RCC_GPIOB_CLK_ENABLE();
	//		__HAL_RCC_GPIOF_CLK_ENABLE();
	//		/* Enable SPI clock */
	//		__HAL_RCC_SPI2_CLK_ENABLE();
	//		/* SPI SCK GPIO pin configuration  */
	//		/*
	//			PA0-SCK	(AF0)
	//			PA3-MISO(AF0)
	//			PB7-MOSI(AF1)
	//			PB8-NSS	(AF1)
	//		*/
	//		GPIO_InitStruct.Pin       = GPIO_PIN_0|GPIO_PIN_3;
	//		GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
	//		GPIO_InitStruct.Pull      = GPIO_PULLDOWN;
	//		GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
	//		GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
	//		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	//
	//		GPIO_InitStruct.Pin       = GPIO_PIN_7|GPIO_PIN_8;
	//		GPIO_InitStruct.Alternate = GPIO_AF1_SPI2;
	//		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	//		HAL_NVIC_SetPriority(SPI2_IRQn, 1, 0);
	//		HAL_NVIC_EnableIRQ(SPI2_IRQn);
	//		//damÅäÖÃ

	//		/*##-3- Configure the DMA ##################################################*/
	//		/* Configure the DMA handler for Transmission process */
	//		HdmaCh1.Instance                 = DMA1_Channel1;
	//		HdmaCh1.Init.Direction           = DMA_MEMORY_TO_PERIPH;
	//		HdmaCh1.Init.PeriphInc           = DMA_PINC_DISABLE;
	//
	//		HdmaCh1.Init.MemInc              = DMA_MINC_ENABLE;
	//		if(hspi->Init.DataSize<=SPI_DATASIZE_8BIT)
	//		{
	//			HdmaCh1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
	//			HdmaCh1.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
	//		}
	//		else
	//		{
	//			HdmaCh1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
	//			HdmaCh1.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
	//		}
	//		HdmaCh1.Init.Mode                = DMA_NORMAL;
	//		HdmaCh1.Init.Priority            = DMA_PRIORITY_VERY_HIGH;

	//		HAL_DMA_Init(&HdmaCh1);

	//		/* Associate the initialized DMA handle to the the SPI handle */
	//		__HAL_LINKDMA(hspi, hdmatx, HdmaCh1);

	//		/* Configure the DMA handler for Transmission process */
	//		HdmaCh2.Instance                 = DMA1_Channel2;

	//		HdmaCh2.Init.Direction           = DMA_PERIPH_TO_MEMORY;
	//		HdmaCh2.Init.PeriphInc           = DMA_PINC_DISABLE;
	//		HdmaCh2.Init.MemInc              = DMA_MINC_ENABLE;
	//		if(hspi->Init.DataSize<=SPI_DATASIZE_8BIT)
	//		{
	//			HdmaCh2.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
	//			HdmaCh2.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
	//		}
	//		else
	//		{
	//			HdmaCh2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
	//			HdmaCh2.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
	//		}
	//		HdmaCh2.Init.Mode                = DMA_NORMAL;
	//		HdmaCh2.Init.Priority            = DMA_PRIORITY_HIGH;

	//		HAL_DMA_Init(&HdmaCh2);

	//		//    /* Associate the initialized DMA handle to the the SPI handle */
	//		__HAL_LINKDMA(hspi, hdmarx, HdmaCh2);

	//		HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 1);
	//		HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

	//		HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 1, 1);
	//		HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
	//	}
}

/**
 * @brief SPI MSP De-Initialization
 *        This function frees the hardware resources used in this example:
 *          - Disable the Peripheral's clock
 *          - Revert GPIO configuration to its default state
 * @param hspi: SPI handle pointer
 * @retval None
 */

void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
{
	if (hspi->Instance == SPI1)
	{
		/*##-1- Reset peripherals ##################################################*/
		__HAL_RCC_SPI1_FORCE_RESET();
		__HAL_RCC_SPI1_RELEASE_RESET();

		/*##-2- Disable peripherals and GPIO Clocks ################################*/
		/* Deconfigure SPI SCK */
		HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
		HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);

		HAL_NVIC_DisableIRQ(SPI1_IRQn);

		HAL_DMA_DeInit(&HdmaCh1);
		HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn);
		//		HAL_DMA_DeInit(&HdmaCh2);
		//		HAL_DMA_DeInit(&HdmaCh3);
		//		HAL_NVIC_DisableIRQ(DMA1_Channel2_3_IRQn);

		//		if(DmaOnFlag&0x01)	{HAL_DMA_DeInit(&HdmaCh1); HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn);}
		//		if(DmaOnFlag>>1&0x01) {HAL_DMA_DeInit(&HdmaCh2);}
		//		if(DmaOnFlag>>2&0x01) {HAL_DMA_DeInit(&HdmaCh3);}
		//		if(DmaOnFlag&0x06) {HAL_NVIC_DisableIRQ(DMA1_Channel2_3_IRQn);}
	}
}

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	if (huart->Instance == USART1)
	{
		/*##-1- Enable peripherals and GPIO Clocks #################################*/
		/* Enable GPIO TX/RX clock */
		USARTx_TX_GPIO_CLK_ENABLE();
		USARTx_RX_GPIO_CLK_ENABLE();

		/* Enable USARTx clock */
		USARTx_CLK_ENABLE();

		/*##-2- Configure peripheral GPIO ##########################################*/
		/* UART TX GPIO pin configuration  */
		GPIO_InitStruct.Pin = USARTx_TX_PIN;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Pull = GPIO_PULLUP;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		GPIO_InitStruct.Alternate = USARTx_TX_AF;

		HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

		/* UART RX GPIO pin configuration  */
		GPIO_InitStruct.Pin = USARTx_RX_PIN;
		GPIO_InitStruct.Alternate = USARTx_RX_AF;

		HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

		/*##-3- Configure the NVIC for UART ########################################*/
		/* NVIC for USART */
		HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);
		HAL_NVIC_EnableIRQ(USARTx_IRQn);
	}
	else if (huart->Instance == USART2)
	{
		/* USER CODE END USART2_MspInit 0 */
		/* Peripheral clock enable */
		__HAL_RCC_USART2_CLK_ENABLE();
		__HAL_RCC_GPIOA_CLK_ENABLE();
		/**USART2 GPIO Configuration

		PA9     ------> USART2_TX
		PA10     ------> USART2_RX
		*/
		GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

		/*##-3- Configure the NVIC for UART ########################################*/
		/* NVIC for USART */
		HAL_NVIC_SetPriority(USART2_IRQn, 0, 1);
		HAL_NVIC_EnableIRQ(USART2_IRQn);
	}
}

void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
	/*##-1- Reset peripherals ##################################################*/
	USARTx_FORCE_RESET();
	USARTx_RELEASE_RESET();

	/*##-2- Disable peripherals and GPIO Clocks #################################*/
	/* Configure UART Tx as alternate function  */
	HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);
	/* Configure UART Rx as alternate function  */
	HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);

	/*##-3- Disable the NVIC for UART ##########################################*/
	HAL_NVIC_DisableIRQ(USARTx_IRQn);
}

/**
 * @brief LPTIM MSP Initialization
 * This function configures the hardware resources used in this example
 * @param hlptim: LPTIM handle pointer
 * @retval None
 */
void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef *hlptim)
{
	__HAL_RCC_LPTIM_CLK_ENABLE(); // RCC_APBENR1_LPTIMEN

	HAL_NVIC_SetPriority(LPTIM1_IRQn, 3, 0);
	HAL_NVIC_EnableIRQ(LPTIM1_IRQn);
}
